# coding: utf-8
#	Magic comment en 1a línia --> strings són UTF-8 i no Ascii (així podem posar accents: àèìòù,áéíóú)
#!/usr/bin/env ruby -w
#	Opcions:-w=Activar Warnings. -KU=$KCODE = "U" --> strings són UTF-8, NO va en Ruby 1.9 !

### Compara calendaris en format iCalendar. 
### Fet a partir de csv2ical.rb (http://github.com/jasonmclaren/csv2ical).
### Author: Joan Ramió.
### Date: 7/6/2012
## TO DO: llistar dinamicament tots els camps d'un event ...

require 'icalendar'
require 'csv'

# Afegir funcions a classe icalendar:
module Icalendar
class Calendar
    def find_event4(dtstart, dtend, summary, location)
      self.events.find {|e| e.dtstart == dtstart  and  e.dtend == dtend  and  e.summary == summary  and e.location == location}
    end 
end
end

    $myname = "ical_compare"
    puts "#{$myname}: Compara calendaris en format iCalendar."
    $cal1 = ""; $cal2 = ""; 
  

    num = 0
    uid = 0
    if ARGV[0] != nil then $cal1 = ARGV[0] end;
    if $cal1 == "--uid"  then  num += 1; uid = 1; end
    if ARGV[num] != nil then $cal1 = ARGV[num] end;
    if ARGV[num+1] != nil then $cal2 = ARGV[num+1] end;
  
    if $cal1.size < 1 then puts "Error: No files specified. Usage is: #{$myname} [--uid] ical1.ics ical2.ics"; exit; end
    if $cal2.size < 1 then puts "Error: No files specified. Usage is: #{$myname} [--uid] ical1.ics ical2.ics"; exit; end
    if !File.exist?($cal1) then puts "Error: File '#{$cal1}' does not exist."; exit; end
    if !File.exist?($cal2) then puts "Error: File '#{$cal2}' does not exist."; exit; end
       
    f1 = File.open($cal1)
    f2 = File.open($cal2)
    cals1 = Icalendar.parse(f1)
    cals2 = Icalendar.parse(f2)
    # no va # assert_equal(cals1.size, 1)
    if cals1.size != 1 then puts "ERROR: Hi ha varios calendaris en primer fitxer."; err += 100; end
    # no va # assert_equal(cals2.size, 1)
    if cals2.size != 1 then puts "ERROR: Hi ha varios calendaris en segon fitxer."; err += 100; end
    ca1 = cals1.first
    ca2 = cals2.first
    if uid == 0 then
      puts "[#{$myname}] - comparant [#{$cal1}]-" + ca1.events.size.to_s + " amb [#{$cal2}]-" + ca2.events.size.to_s + " per items exactes ..."
    else
      puts "[#{$myname}] - comparant [#{$cal1}]-" + ca1.events.size.to_s + " amb [#{$cal2}]-" + ca2.events.size.to_s + " per UIDs ..."
    end  
    
err = 0
for num in 0..ca1.events.size-1

ev1 = ca1.events[num]
if uid == 1 then
  ev2 = ca2.find_event(ev1.uid)
else
	ev2 = ca2.find_event4(ev1.dtstart, ev1.dtend, ev1.summary, ev1.location)
end
if ev2 == nil   then  err += 1 ; puts "Error item #{num} '#{ev1.summary}' no trobat en 2n cal: '" + ev1.dtstart.to_s + "','" + ev1.dtend.to_s + "','" + ev1.summary.to_s + "','" + ev1.location.to_s + "'."  ;  end
next if ev2 == nil

if  ev1.dtstart  != ev2.dtstart  then   puts "Item #{uid==1 ? ev1.uid : num} diference in dtstart:\n'" + ev1.dtstart.to_s + "'\n'" + ev2.dtstart.to_s + "'"; err += 1; end
if  ev1.dtend    != ev2.dtend    then   puts "Item #{uid==1 ? ev1.uid : num} diference in dtend:\n'" + ev1.dtend.to_s + "'\n'" + ev2.dtend.to_s + "'"; err += 1; end
# Error if both summary are nil
if  ev1.summary.nil? or ev2.summary.nil? or (ev1.summary.strip  != ev2.summary.strip)  then   puts "Item #{uid==1 ? ev1.uid : num} diference in summary:\n'" + ev1.summary.to_s + "'\n'" + ev2.summary.to_s + "'"; err += 1; end
if  ev1.location != ev2.location then 
	# Both are not nil
	if  ev1.location.nil? or ev2.location.nil? or (ev1.location.strip != ev2.location.strip) then   puts "Item #{uid==1 ? ev1.uid : num} diference in location:\n'" + ev1.location.to_s + "'\n'" + ev2.location.to_s + "'"; err += 1; end
end	
if  ev1.description != ev2.description then 
	# Both are not nil
	if  ev1.description.nil? or ev2.description.nil? or (ev1.description.strip != ev2.description.strip) then   puts "Item #{uid==1 ? ev1.uid : num} diference in description:\n'" + ev1.description.to_s + "'\n'" + ev2.description.to_s + "'"; err += 1; end
end	
	
end
if uid == 0 then
  puts "[#{$myname}] - comparat [#{$cal1}]-" + ca1.events.size.to_s + " amb [#{$cal2}]-" + ca2.events.size.to_s + " per items exactes."
else
  puts "[#{$myname}] - comparat [#{$cal1}]-" + ca1.events.size.to_s + " amb [#{$cal2}]-" + ca2.events.size.to_s + " per UIDs."
end     
if ca2.events.size != ca1.events.size then puts "ERROR: Numero de items en calendaris diferents: " + ca1.events.size.to_s + " i " + ca2.events.size.to_s; err += (ca2.events.size - ca1.events.size).abs; end
puts "[#{$myname}] - completats " + (num + 1).to_s + " items."
puts "[#{$myname}] - detectades " + err.to_s + " diferencies."
exit err
